home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / keyb / stuft310.zip / STUFFIT.ASM < prev    next >
Assembly Source File  |  1991-04-21  |  49KB  |  1,997 lines

  1.    PAGE 80,132
  2.    TITLE "StuffIt, Delayed keyboard stuffer. (C) Terje Mathisen 1989-91"
  3.  
  4. Version EQU 310h
  5. VerStr  EQU '3.10ß'
  6.  
  7. ;       LOCALS                  ; Use TASM features for easier development.
  8. ;       NOJUMPS
  9.  
  10. TicksPrDay      EQU 1573041
  11. TicksPrHour     EQU 65543
  12.  
  13. BIOS SEGMENT AT 40h
  14.         ORG 1Ah
  15. BufferHead      dw ?
  16. BufferTail      dw ?
  17. BufferStart     dw 16 dup (?)
  18. BufferEnd       LABEL word
  19.  
  20.         ORG 49h
  21. VideoMode       db ?
  22. CrtWidth        dw ?
  23.  
  24.         ORG 4Eh
  25. CurrStart       dw ?
  26. Cursor          dw ?
  27.  
  28.         ORG 6Ch
  29. BIOS_Timer      dw 2 dup (?)
  30. BIOS ENDS
  31.  
  32. BOOT SEGMENT AT 0F000h
  33.         ORG 0FFF0h
  34. RebootLocation  LABEL FAR
  35. BOOT ENDS
  36.  
  37. ; To reduce the resident size of StuffIt, the script is compressed into tokens
  38. ; using the following algorithm:
  39. ;
  40. ; 0 means that this is a character code which will be followed by a scan code
  41. ;
  42. ; 224 means the same as 0, (224 is lead-in code for the cursor keypad on the
  43. ; enhanced keyboard.)
  44. ;
  45. ; 254 is an escape character, followed by a char:scan pair. This is also used
  46. ; if we need to enter Chr(254) or Chr(255)
  47. ;
  48. ; 255 is the lead-in for an extended function code. It will be followed by
  49. ; one of these codes:
  50. ;
  51. ; Codes for extended functions, i.e not normal keys:
  52.  
  53. REBOOT_CODE     = 0
  54. ATTIME_CODE     = 1
  55. DELTATIME_CODE  = 2
  56. FIND_CODE       = 3
  57. PROMPT_CODE     = 4
  58. PRTSCRN_CODE    = 5
  59. BREAK_CODE      = 6
  60.  
  61. ; Use 255 to signal that the following is an extended function
  62.  
  63. EXTENDED_CODE   = 255
  64.  
  65. ; Use 254 as lead-in for keys that need both char & scan.
  66.  
  67. GETWORD_CODE    = 254
  68.  
  69. ; All other codes (1-221,223-253) are presumed to be single characters to
  70. ; place in the kbd buffer. All of them will receive the same scan code (2).
  71. ; If your application cannot accept this, you must use the {c} or [c] syntax,
  72. ; where <c> is any character. This will be translated to the US std enh kbd
  73. ; char:scan pair.
  74.  
  75.  
  76. CODE SEGMENT PARA PUBLIC 'code'
  77.         ASSUME CS:CODE,DS:NOTHING,ES:NOTHING
  78.         ORG 0
  79. PspStart label byte
  80.  
  81.         ORG 5Ch
  82. ResidentSize    dw ?
  83.  
  84. ;LowStart label byte
  85.  
  86.         ORG 80h
  87. CommandLen      db ?
  88. CommandLine     LABEL BYTE
  89.  
  90.         ORG 100h
  91. start:
  92.         jmp init
  93.  
  94. Semafor equ 'ST'                        ; Short for STuffit
  95.  
  96. LowStart label byte
  97. HighStart label byte
  98.  
  99. MoveDown EQU HighStart - LowStart       ; Relocation factor for resident
  100.                                         ; part of StuffIt
  101.  
  102. Int2F   proc far
  103.         cmp ax,0E000h
  104.          je @@maybe
  105.  
  106. @@chain:
  107. ;       jmp [OldInt2F]
  108.         db 0EAh
  109. OldInt2F dd ?
  110.  
  111. @@maybe:
  112.         cmp dx,Semafor                  ; Be safe, insist on semafor in DX
  113.          jne @@chain
  114.  
  115. @@We_Are_Here:
  116.         mov al,0FFh
  117.         mov dx,cs
  118.         mov bx,Version
  119.  
  120.         iret
  121.  
  122. Int2F   endp
  123.  
  124.  
  125. ; Here comes the actual, INT 8, code, which will run on every timer tick to
  126. ; execute the tokenized script.
  127. ;
  128. ; To reduce the performance overhead of having StuffIt loaded, I use a dirty
  129. ; trick: Self-modifying code.
  130. ;
  131. ; When the script has finished, the total overhead is reduced to just
  132. ; 3 instructions: PUSHF / CALL (FAR IMMEDIATE) OldTimer / IRET
  133.  
  134. PUSH_AX_OPCODE EQU  50h                 ; Opcode for PUSH AX, used when active
  135. IRET_OPCODE    EQU 0CFh                 ; Opcode for IRET, used when disabled
  136.  
  137. MyTimer PROC FAR
  138.         pushf
  139. ;       call [OldTimer]                 ; Call the old timer code first, to
  140.         db 09Ah                         ; do it's stuff and re-enable the HW.
  141. OldTimer dw ?,?
  142.  
  143. SelfModify label byte                   ; This will be IRET when idle
  144.         push ax                         ; PUSH AX = 50h, IRET = 0CFh
  145.  
  146. ; The [active] flag is initialized to -1. This way I can use an INC
  147. ; instruction to detect the first entry into this code. Multiple
  148. ; invocations will jump directly to the exit code, with very little
  149. ; overhead. (A total of only 7 instructions and 1 short jump.)
  150.  
  151.         inc byte ptr [cs:active-MoveDown] ;  INC from -1 to 0
  152.          jnz Already_Active
  153.  
  154.         STI
  155.         CLD
  156.  
  157.         push bx
  158.         push cx
  159.  
  160.         push dx
  161.         push si
  162.         push di
  163.         push ds
  164.         push es
  165.  
  166.         push cs
  167.         pop ds
  168.         ASSUME DS:CODE
  169.  
  170.         mov es,[BiosSeg-MoveDown]       ; I store 40h in a memory variable and
  171.                                         ; load ES from it, as this saves one
  172.                                         ; instruction vs MOV AX,40/MOV ES,AX
  173.         ASSUME ES:BIOS
  174.  
  175.         call word ptr [StuffMode-MoveDown] ; State machine, call the current
  176.                                         ; state handler.
  177.  
  178.         pop es
  179.         pop ds
  180.         pop di
  181.         pop si
  182.         pop dx
  183.  
  184.         pop cx
  185.         pop bx
  186.  
  187.         ASSUME CS:CODE,DS:NOTHING,ES:NOTHING
  188.  
  189.         CLI
  190.  
  191. Already_Active:
  192.  
  193.         dec byte ptr [cs:active-MoveDown]
  194.  
  195.         pop ax
  196.         iret
  197. MyTimer ENDP
  198.  
  199.         ASSUME CS:CODE,DS:CODE,ES:BIOS
  200.  
  201. StuffFinished:
  202.         mov [SelfModify-MoveDown],IRET_OPCODE   ; Disable by self-modifying
  203.                                         ; May be re-enabled by a later
  204.                                         ; invocation of StuffIt.
  205.         ret
  206.  
  207. NextKey proc near
  208.         mov si,[StuffPtr-MoveDown]
  209. GetNext:
  210.         cmp si,[StuffEnd-MoveDown]
  211.          jae StuffFinished
  212.  
  213.         lodsb
  214.         cmp al,GETWORD_CODE
  215.          ja Extended                    ; Extended function
  216.          je @@GetBoth                   ; 254 => char, scan follows
  217.  
  218.         mov ah,2                        ; Simulate scan = 2 for normal chars
  219.         cmp al,224                      ; Character for Enh.Kbd new keys
  220.          je @@GetScan
  221.  
  222.         or al,al
  223.          jne stuff
  224.  
  225. @@GetScan:
  226.         mov ah,[si]
  227.         inc si
  228.          jmp short stuff
  229.  
  230. @@GetBoth:
  231.         lodsw
  232. Stuff:
  233.         CLI
  234.         mov di,[BufferTail]
  235.         stos word ptr [BIOS:di]
  236.         cmp di, OFFSET BufferEnd
  237.          jb @@1
  238.         mov di, OFFSET BufferStart
  239. @@1:
  240.         cmp di,[BufferHead]
  241.          je @@Overflow
  242.         mov [BufferTail],di
  243.         STI
  244. StuffOK:
  245.         mov [StuffPtr-MoveDown],si
  246.          jmp GetNext
  247.  
  248. @@OverFlow:
  249.         STI
  250.         ret
  251. NextKey ENDP
  252.  
  253. ExtendedTable label word
  254.   dw Reboot      - MoveDown
  255.   dw AbsTime     - MoveDown
  256.   dw DeltaTime   - MoveDown
  257.   dw StartFind   - MoveDown
  258.   dw StartPrompt - MoveDown
  259.   dw PrtScrn     - MoveDown
  260.   dw CtrlBreak   - MoveDown
  261.  
  262. NrOfCodes = ($ - offset ExtendedTable) SHR 1
  263.  
  264. Extended PROC near
  265.         lodsb                           ; Get function code!
  266.         cmp al,NrOfCodes
  267.          jae StuffFinished              ; Program Error! Abort the script!
  268.  
  269.         cbw                             ; All codes are <= 127, so CBW is OK!
  270.         mov bx,ax
  271.         shl bx,1
  272.         jmp ExtendedTable[bx - MoveDown] ; Jump to function handler
  273.  
  274. Extended endp
  275.  
  276. Reboot proc near
  277.         mov word ptr [BIOS: 72h],1234h  ; == Warm Boot (CtrlAltDel)
  278.         jmp RebootLocation              ; == F000:FFF0
  279. Reboot endp
  280.  
  281. PrtScrn proc near
  282.         int     5
  283.         jmp     GetNext
  284. PrtScrn endp
  285.  
  286. CtrlBreak proc near
  287.         int     1Bh
  288.         xor     ax,ax
  289.         jmp     Stuff
  290. CtrlBreak endp
  291.  
  292. AbsTime:                                ; Both Abs time & Delta time land here
  293. DeltaTime:                              ; ---- " ----
  294.  
  295. GetTime proc near
  296.  
  297.         cmp al, DELTATIME_CODE
  298.         lodsw                           ; Next 3 bytes is # of ticks
  299.         mov dl,[si]
  300.          jz @@TimeOk                    ; Delta time, so wait # of ticks
  301.  
  302. ; Wait until time equal: Calculate remaining ticks
  303.  
  304.         sub ax,[Bios_Timer]
  305.         sbb dl,BYTE PTR [Bios_Timer+2]
  306.          jae @@TimeOk
  307.  
  308.         add ax,TicksPrDay AND 0FFFFh
  309.         adc dl,TicksPrDay Shr 16
  310.  
  311. @@TimeOK:
  312.         inc si
  313.         mov [StuffPtr-MoveDown],si               ; Point to next byte
  314.  
  315.         sub dh,dh                       ; Fill top of DX with 0
  316.         or ax,dx
  317.          jz @@WaitZero                  ; Special case, wait for empty kbd
  318.  
  319.         mov [CountLow-MoveDown],ax
  320.         mov [